home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Source.bin / Timer.java < prev    next >
Text File  |  1998-08-21  |  16KB  |  581 lines

  1. package symantec.itools.util;
  2.  
  3. import java.awt.Component;
  4. import java.awt.event.ActionListener;
  5. import java.awt.event.ActionEvent;
  6. import java.beans.PropertyVetoException;
  7. import java.beans.PropertyChangeListener;
  8. import java.beans.VetoableChangeListener;
  9. import java.awt.event.ActionListener;
  10. import java.awt.AWTEvent;
  11. import java.awt.AWTEventMulticaster;
  12.  
  13. //    05/30/97    LAB    Updated to support Java 1.1
  14. //    06/06/97    LAB    Removed deprecated (unusable in 1.1) functions:
  15. //                    public void setEventType(int type)
  16. //                    public int getEventType()
  17. //                    public void setTarget(Component t)
  18. //                    public Component getTarget()
  19. //    06/24/97    LAB    Changed the behavior of the start and stop
  20. //                    methods to actually start and stop the thread
  21. //                    instead of suspending and resuming it.  Added
  22. //                    pause() and resume() for this purpose.
  23. //  07/23/97    CAR implemented readObject
  24. //    08/19/97    LAB    Fixed a bug where Timer would keep going even if repeat was set to false.
  25. //                    Fixed resume to only resume if currently paused.  Changed property
  26. //                    names used by firePropertyChange to follow the naming conventions set
  27. //                    forth in the Bean Spec. (lowwer case first letter, unless second letter
  28. //                    is capitalized too).  Made package level data protected.
  29. //    10/11/97    LAB    Fixed a problem where if stop was called before the original delay
  30. //                    elapsed it would wait until the delay elapsed (Thanks KSB.  Addresses
  31. //                    Mac Bug #9172).  Fixed resume to start the timer if it was not
  32. //                    started (also avoids Exception if the thread was dead).    Now no
  33. //                    threads are created or accessed at design time (Addresses Mac Bug
  34. //                    #9187).  Fixed a problem when calling stop on a stopped timer would
  35. //                    cause an exception (Addresses Mac Bug #9178).  Added restart method.
  36. //                    Fixed stoping a timer would reset the repeat property (Addresses Mac
  37. //                    Bug #9171).
  38. //    10/14/97    LAB    Added isEnabled and getEnabled for compatability with the backrunner
  39. //                    (Addresses Mac Bug #9268).
  40. //    10/16/97    LAB    Made methods synchronized as needed.  Fixed a problem where stopping,
  41. //                    then starting would sometimes result in no events being fired (Addresses
  42. //                    Mac Bug #9376).
  43. //    10/17/97    LAB    Made thread return when it was interrupted, and check in start for interrupted
  44. //                    thread before resuming it (re-fixes #9376).
  45.  
  46. /**
  47.  *
  48.  * Sets a timer to wait before an action event is posted to a component.
  49.  * The caller can specify the target component, the event to send to the
  50.  * component, and the time delay.
  51.  *
  52.  * The timer is implemented as a thread.  The one of the start(...) methods should
  53.  * be called to start the thread.
  54.  *
  55.  *
  56.  * @version 1.0, Nov 26, 1996
  57.  *
  58.  * @author    Symantec
  59.  *
  60.  */
  61. public class Timer implements Runnable, java.io.Serializable
  62. {
  63.     /**
  64.      * Creates a timer with the default delay.
  65.      * After 1000 miliseconds this timer will fire an ActionEvent.
  66.      * It will not repeat.
  67.      */
  68.     public Timer()
  69.     {
  70.         this(1000, false);
  71.     }
  72.  
  73.     /**
  74.      * Creates a timer with specified delay.
  75.      * After the specified delay this timer will fire an ActionEvent.
  76.      * It will not repeat.
  77.      * @param d the delay in milliseconds
  78.      */
  79.     public Timer(int d)
  80.     {
  81.         this(d, false);
  82.     }
  83.  
  84.     /**
  85.      * Creates a timer with specified repeat setting and the default delay.
  86.      * After 1000 miliseconds this timer will fire an ActionEvent.
  87.      * It may repeat, depending on r.
  88.      * @param r if true, reset and repeat after generating the event
  89.      */
  90.     public Timer(boolean r)
  91.     {
  92.         this(1000, r);
  93.     }
  94.  
  95.     /**
  96.      * Creates a timer with specified delay and repeat setting.
  97.      * After the specified delay this timer will fire an ActionEvent.
  98.      * It may repeat, depending on r.
  99.      * @param d the delay in milliseconds
  100.      * @param r if true, reset and repeat after generating the event
  101.      */
  102.     public Timer(int d, boolean r)
  103.     {
  104.         delay            = d;
  105.         repeat            = r;
  106.         execute            = false;
  107.         live            = false;
  108.         isDesignTime    = java.beans.Beans.isDesignTime();
  109.         if(!isDesignTime)
  110.             thread = new Thread(this);
  111.     }
  112.  
  113.     /**
  114.      * @deprecated
  115.      * @see Timer#Timer(int, boolean)
  116.      */
  117.     public Timer(Component t)
  118.     {
  119.         this(1000);
  120.     }
  121.  
  122.     /**
  123.      * @deprecated
  124.      * @see Timer#Timer(int, boolean)
  125.      */
  126.     public Timer(Component t, int d)
  127.     {
  128.         this(d, false);
  129.     }
  130.  
  131.     /**
  132.      * @deprecated
  133.      * @see Timer#Timer(int, boolean)
  134.      */
  135.     public Timer(Component t, int d, boolean r)
  136.     {
  137.         this(d, r);
  138.     }
  139.  
  140.     /**
  141.      * @deprecated
  142.      * @see Timer#Timer(int, boolean)
  143.      */
  144.     public Timer(Component t, int d, boolean r, int e)
  145.     {
  146.         this(d, r);
  147.     }
  148.  
  149.     /**
  150.      * Sets the delay time for this timer.
  151.      * @param d the delay in milliseconds.  This delay will be used starting
  152.      *          after the current delay elapses
  153.      *
  154.      * @exception PropertyVetoException
  155.      * if the specified property value is unacceptable
  156.      * @see #getDelay()
  157.      */
  158.     public void setDelay(int d) throws PropertyVetoException
  159.     {
  160.         Integer newValue = new Integer(d);
  161.         Integer oldValue = new Integer(delay);
  162.  
  163.         vetos.fireVetoableChange("delay", oldValue, newValue);
  164.  
  165.         delay = d;
  166.  
  167.         changes.firePropertyChange("delay", oldValue, newValue);
  168.     }
  169.  
  170.     /**
  171.      * Obtains the delay time setting for this timer.
  172.      * @return the current delay setting for this timer, in milliseconds
  173.      * @see #setDelay(int)
  174.      */
  175.     public int getDelay()
  176.     {
  177.         return delay;
  178.     }
  179.  
  180.  
  181.     /**
  182.      * Changes the repeat setting of the timer.
  183.      * If the repeat setting is false a single event will be generated.  When
  184.      * set to true the timer produces a series of events.
  185.      *
  186.      * @param f reset and repeat after generating the event
  187.      * @exception PropertyVetoException
  188.      * if the specified property value is unacceptable
  189.      * @see #isRepeat
  190.      */
  191.     public void setRepeat(boolean f) throws PropertyVetoException
  192.     {
  193.         Boolean newValue = new Boolean(f);
  194.         Boolean oldValue = new Boolean(repeat);
  195.  
  196.         vetos.fireVetoableChange("repeat", oldValue, newValue);
  197.  
  198.         repeat = f;
  199.  
  200.         changes.firePropertyChange("repeat", oldValue, newValue);
  201.     }
  202.  
  203.     /**
  204.      * Obtains the repeat setting of the timer.
  205.      * @return true if this timer is set to repeat, false if this timer does not repeat
  206.      * @see #setRepeat
  207.      */
  208.     public boolean isRepeat()
  209.     {
  210.         return repeat;
  211.     }
  212.  
  213.     /**
  214.      * @deprecated
  215.      * @see #isRepeat()
  216.      */
  217.     public boolean getRepeat()
  218.     {
  219.         return isRepeat();
  220.     }
  221.  
  222.     /**
  223.      * Is the timer currently enabled
  224.      * @return true if the timer is running.
  225.      */
  226.      public boolean isEnabled()
  227.      {
  228.          return live;
  229.      }
  230.  
  231.     /**
  232.      * @deprecated
  233.      * Needed for compatability with backrunner.
  234.      */
  235.      public boolean getEnabled()
  236.      {
  237.          return isEnabled();
  238.      }
  239.  
  240.     /**
  241.      * Pauses the timer.
  242.      * Differs from stop in that the timer
  243.      * is continued from whatever state it was in before
  244.      * pausing.
  245.      * <p>
  246.      * start() and stop() overrule this function.
  247.      * @see #resume
  248.      * @see #start
  249.      * @see #stop
  250.      */
  251.     synchronized public void pause()
  252.     {
  253.         execute = false;
  254.         if(thread.isAlive())
  255.             thread.suspend();
  256.  
  257.         if(thread.isAlive())
  258.             thread.suspend();
  259.     }
  260.  
  261.     /**
  262.      * Resumes the timer.
  263.      * Differs from start in that the timer
  264.      * is continued from whatever state it was in before
  265.      * pausing.
  266.      * <p>
  267.      * start() and stop() overrule this function
  268.      * @see #pause
  269.      * @see #start
  270.      * @see #stop
  271.      */
  272.     synchronized public void resume()
  273.     {
  274.         if(!execute)
  275.         {
  276.             execute = true;
  277.             if(thread.isAlive())
  278.                 thread.resume();
  279.             else
  280.                 start();
  281.         }
  282.     }
  283.  
  284.     /**
  285.      * Starts the timer with existing settings.
  286.      * @see #start(int)
  287.      * @see #start(boolean)
  288.      * @see #start(int, boolean)
  289.      * @see #stop
  290.      * @see #run
  291.      */
  292.     synchronized public void start()
  293.     {
  294.         execute = true;
  295.         live    = true;
  296.         if(!isDesignTime)
  297.         {
  298.             if(thread.isAlive() && !thread.isInterrupted())
  299.             {
  300.                 if(thread.isAlive())
  301.                     thread.resume();
  302.             }
  303.             else
  304.             {
  305.                 thread    = new Thread(this);
  306.                 thread.start();
  307.             }
  308.         }
  309.     }
  310.  
  311.     /**
  312.      * Starts the timer using the specified delay.
  313.      * @param d the delay in milliseconds
  314.      * @exception PropertyVetoException
  315.      * if the specified property value is unacceptable
  316.      * @see #start()
  317.      * @see #start(boolean)
  318.      * @see #start(int, boolean)
  319.      * @see #stop
  320.      * @see #run
  321.      */
  322.     synchronized public void start(int d) throws PropertyVetoException
  323.     {
  324.         setDelay(d);
  325.  
  326.         start();
  327.     }
  328.  
  329.     /**
  330.      * Starts the timer using the specified repeat setting.
  331.      * @param r reset and repeat after generating the event
  332.      * @exception PropertyVetoException
  333.      * if the specified property value is unacceptable
  334.      * @see #start()
  335.      * @see #start(int)
  336.      * @see #start(int, boolean)
  337.      * @see #stop
  338.      * @see #run
  339.      */
  340.     synchronized public void start(boolean r) throws PropertyVetoException
  341.     {
  342.         setRepeat(r);
  343.  
  344.         start();
  345.     }
  346.  
  347.     /**
  348.      * Starts the timer using the specified delay and repeat settings.
  349.      * @param d the delay in milliseconds
  350.      * @param r reset and repeat after generating the event
  351.      * @exception PropertyVetoException
  352.      * if the specified property value is unacceptable
  353.      * @see #start()
  354.      * @see #start(int)
  355.      * @see #start(boolean)
  356.      * @see #stop
  357.      * @see #run
  358.      */
  359.     synchronized public void start(int d, boolean r) throws PropertyVetoException
  360.     {
  361.         setDelay(d);
  362.         setRepeat(r);
  363.  
  364.         start();
  365.     }
  366.  
  367.     /**
  368.      * Restarts the timer immediately with the current delay value.
  369.      * This will start a stopped timer.
  370.      * @see #start()
  371.      * @see #stop()
  372.      */
  373.     synchronized public void restart()
  374.     {
  375.         stop();
  376.         start();
  377.     }
  378.  
  379.     /**
  380.      * Stops the timer.  After return the timer will generate no more events.
  381.      * @see #start
  382.      */
  383.     synchronized public void stop()
  384.     {
  385.         execute        = false;
  386.         live        = false;
  387.         if(!isDesignTime && thread.isAlive())
  388.         {
  389.             thread.interrupt();
  390.         }
  391.     }
  392.  
  393.     /**
  394.      * The thread body.  This method is called by the Java virtual machine in response to a
  395.      * start call by the user.
  396.      * @see #start()
  397.      * @see #start(int)
  398.      * @see #start(boolean)
  399.      * @see #start(int, boolean)
  400.      * @see #stop
  401.      */
  402.     public void run()
  403.     {
  404.         if(!execute)
  405.         {
  406.             thread.suspend();
  407.         }
  408.         while(live)
  409.         {
  410.             do
  411.             {
  412.                 repeating = repeat;
  413.                 try
  414.                 {
  415.                     thread.sleep(delay);
  416.                     if (execute)
  417.                     {
  418.                         sourceActionEvent();
  419.                     }
  420.                 }
  421.                 catch (InterruptedException e) { return; }
  422.             }
  423.             while (repeating && live);
  424.  
  425.             if((!execute && live) || !repeating)
  426.             {
  427.                 thread.suspend();
  428.             }
  429.         }
  430.     }
  431.  
  432.     /**
  433.      * Sets the command name of the action event fired by this button.
  434.      * @param command Tthe name of the action event command fired by this button
  435.      * @see #getActionCommand
  436.      * @exception PropertyVetoException
  437.      * if the specified property value is unacceptable
  438.      */
  439.     public void setActionCommand(String command) throws PropertyVetoException
  440.     {
  441.         String oldValue = actionCommand;
  442.  
  443.         vetos.fireVetoableChange("actionCommand", oldValue, command);
  444.         actionCommand = command;
  445.         changes.firePropertyChange("actionCommand", oldValue, command);
  446.     }
  447.  
  448.     /**
  449.      * Returns the command name of the action event fired by this button.
  450.      * @see #setActionCommand
  451.      */
  452.     public String getActionCommand()
  453.     {
  454.         return actionCommand;
  455.     }
  456.  
  457.     /**
  458.      * Adds the specified action listener to receive action events
  459.      * from this button.
  460.      * @param l the action listener
  461.      */
  462.     public void addActionListener(ActionListener l)
  463.     {
  464.         actionListener = AWTEventMulticaster.add(actionListener, l);
  465.     }
  466.  
  467.     /**
  468.      * Removes the specified action listener so it no longer receives
  469.      * action events from this button.
  470.      * @param l the action listener
  471.      */
  472.     public void removeActionListener(ActionListener l)
  473.     {
  474.         actionListener = AWTEventMulticaster.remove(actionListener, l);
  475.     }
  476.  
  477.     /**
  478.      * Fires an action event to the listeners.
  479.      * @see #setActionCommand
  480.      */
  481.     public void sourceActionEvent()
  482.     {
  483.         if (actionListener != null)
  484.             actionListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
  485.     }
  486.  
  487.     /**
  488.      * Adds a listener for all property change events.
  489.      * @param listener the listener to add
  490.      * @see #removePropertyChangeListener
  491.      */
  492.     public void addPropertyChangeListener(PropertyChangeListener listener)
  493.     {
  494.         changes.addPropertyChangeListener(listener);
  495.     }
  496.  
  497.     /**
  498.      * Removes a listener for all property change events.
  499.      * @param listener the listener to remove
  500.      * @see #addPropertyChangeListener
  501.      */
  502.     public void removePropertyChangeListener(PropertyChangeListener listener)
  503.     {
  504.         changes.removePropertyChangeListener(listener);
  505.     }
  506.  
  507.     /**
  508.      * Adds a listener for all vetoable property change events.
  509.      * @param listener the listener to add
  510.      * @see #removeVetoableChangeListener
  511.      */
  512.     public void addVetoableChangeListener(VetoableChangeListener listener)
  513.     {
  514.         vetos.addVetoableChangeListener(listener);
  515.     }
  516.  
  517.     /**
  518.      * Removes a listener for all vetoable property change events.
  519.      * @param listener the listener to remove
  520.      * @see #addVetoableChangeListener
  521.      */
  522.     public void removeVetoableChangeListener(VetoableChangeListener listener)
  523.     {
  524.         vetos.removeVetoableChangeListener(listener);
  525.     }
  526.  
  527.     private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
  528.         in.defaultReadObject();
  529.  
  530.         execute   = false;
  531.         thread    = new Thread(this);
  532.     }
  533.  
  534.     /**
  535.      * Reserved.
  536.      */
  537.     protected Component            target;
  538.     /**
  539.      * Reserved.
  540.      */
  541.     protected int                    eventType;
  542.     /**
  543.      * The value of the Repeat property.
  544.      */
  545.        protected boolean                repeat;
  546.     /**
  547.      * Internal use. True if Repeat property true, and Timer is in its repeat timing loop.
  548.      */
  549.     protected boolean                repeating;
  550.     /**
  551.      * True while timer thread is running.
  552.      */
  553.     protected boolean                execute;
  554.     /**
  555.      * True if the timer is enabled and running.
  556.      */
  557.     protected boolean                live;
  558.     /**
  559.      * True if we're in the Java development environment.
  560.      */
  561.     protected boolean                isDesignTime;
  562.     /**
  563.      * The value of the Delay property.
  564.      */
  565.     protected int                    delay;
  566.     /**
  567.      * The value of the Action Command property.
  568.      */
  569.     protected String                actionCommand;
  570.     /**
  571.      * Listener(s) that get notified when an ActionEvent is generated.
  572.      */
  573.     protected ActionListener        actionListener = null;
  574.     /**
  575.      * The timer's thread.
  576.      */
  577.     transient protected Thread    thread;
  578.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  579.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  580. }
  581.